package com.caochenlei.codebuilder.main;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JTextField;

import com.caochenlei.codebuilder.config.DatabaseConfigUtil;
import com.caochenlei.codebuilder.config.DatabasesConfigUtil;
import com.caochenlei.codebuilder.entity.Database;
import com.caochenlei.codebuilder.entity.Table;
import com.caochenlei.codebuilder.utils.Code;
import com.caochenlei.codebuilder.utils.DatabaseMetaDataUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CodeStruct {
	private static Logger logger = LoggerFactory.getLogger(CodeStruct.class);

	private JFrame codeStructFrame;
	private JTextField textField_0;
	private JTextField textField_1;
	private JTextField textField_2;
	private JTextField textField_3;
	final JComboBox<String> comboBox_0 = new JComboBox<String>();
	final JComboBox<String> comboBox_1 = new JComboBox<String>();
	JButton button_0 = new JButton("获取数据库名");
	JButton button_1 = new JButton("开始生成代码");

	private Map<String, Map<String, String>> dbConfig = null;
	private String dbIp = null;
	private String dbPort = null;
	private String dbName = null;
	private String dbUrl = null;
	private String dbUser = null;
	private String dbPassword = null;
	private String dbType = null;
	private String dbDriverName = null;
	private String dbDataSourceType = null;
	private String dbDialect = null;
	private String dbGenerator = null;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		/**
		 * Use the current system skin.
		 */
		try {
			javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (Exception e) {
			e.printStackTrace();
		}

		/**
		 * Initialize the form and start it.
		 */
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					CodeStruct window = new CodeStruct();
					window.codeStructFrame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public CodeStruct() {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		dbConfig = DatabasesConfigUtil.read("databases");

		codeStructFrame = new JFrame();
		codeStructFrame.setTitle("CodeBuilder");
		codeStructFrame.setBounds(760, 290, 385, 415);
		codeStructFrame.setResizable(false);
		codeStructFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		codeStructFrame.getContentPane().setLayout(null);

		JLabel label_0 = new JLabel("数据库类型：");
		label_0.setBounds(21, 21, 75, 30);
		codeStructFrame.getContentPane().add(label_0);

		JLabel label_1 = new JLabel("数据库地址：");
		label_1.setBounds(21, 69, 75, 30);
		codeStructFrame.getContentPane().add(label_1);

		JLabel label_2 = new JLabel("数据库端口：");
		label_2.setBounds(21, 117, 75, 30);
		codeStructFrame.getContentPane().add(label_2);

		JLabel label_3 = new JLabel("数据库用户：");
		label_3.setBounds(21, 165, 75, 30);
		codeStructFrame.getContentPane().add(label_3);

		JLabel label_4 = new JLabel("数据库密码：");
		label_4.setBounds(21, 213, 75, 30);
		codeStructFrame.getContentPane().add(label_4);

		JLabel label_5 = new JLabel("数据库名称：");
		label_5.setBounds(21, 261, 75, 30);
		codeStructFrame.getContentPane().add(label_5);

		// ==================================================数据库配置选取开始==================================================
		comboBox_0.setBounds(96, 21, 250, 30);
		// 1.加载数据库列表
		for (String database : dbConfig.keySet()) {
			comboBox_0.addItem(database);
		}
		// 2.监听下拉列表框
		comboBox_0.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent actionEvent) {
				// 重新加载数据库配置
				reloadSettings(dbConfig, comboBox_0, comboBox_1);
			}
		});
		codeStructFrame.getContentPane().add(comboBox_0);
		// ==================================================数据库配置选取结束==================================================
		comboBox_1.setBounds(96, 261, 250, 30);
		codeStructFrame.getContentPane().add(comboBox_1);

		textField_0 = new JTextField();
		textField_0.setColumns(10);
		textField_0.setBounds(96, 69, 250, 30);
		codeStructFrame.getContentPane().add(textField_0);

		textField_1 = new JTextField();
		textField_1.setColumns(10);
		textField_1.setBounds(96, 117, 249, 30);
		codeStructFrame.getContentPane().add(textField_1);

		textField_2 = new JTextField();
		textField_2.setColumns(10);
		textField_2.setBounds(96, 165, 250, 30);
		codeStructFrame.getContentPane().add(textField_2);

		textField_3 = new JTextField();
		textField_3.setColumns(10);
		textField_3.setBounds(96, 213, 249, 30);
		codeStructFrame.getContentPane().add(textField_3);

		reloadSettings(dbConfig, comboBox_0, comboBox_1);

		JSeparator separator = new JSeparator();
		separator.setBounds(0, 310, 370, 2);
		codeStructFrame.getContentPane().add(separator);

		// ==================================================获取数据库名开始==================================================
		button_0.setBounds(21, 328, 130, 35);
		codeStructFrame.getContentPane().add(button_0);
		button_0.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent mouseEvent) {
				try {
					// 清除数据库表名列表
					comboBox_1.removeAllItems();

					// 开启数据库连接列表
					comboBox_1.setEnabled(true);

					// 获取数据库文本信息
					dbType = (String) comboBox_0.getSelectedItem();
					dbIp = textField_0.getText();
					dbPort = textField_1.getText();
					dbUser = textField_2.getText();
					dbPassword = textField_3.getText();
					dbUrl = dbConfig.get(dbType).get("dbUrl");
					dbDriverName = dbConfig.get(dbType).get("dbDriverName");

					// 获取数据库基本配置
					String dbUrlTemp = DatabasesConfigUtil.replaceUrlConfig(dbUrl, dbIp, dbPort, "");

					// 获取数据库表名列表
					if (dbType.equals("ORACLE")) {
						comboBox_1.addItem("ORCL");
					} else {
						DatabaseMetaDataUtil databaseMetaDate = new DatabaseMetaDataUtil(dbDriverName, dbUrlTemp, dbUser, dbPassword);
						List<String> dbNames = databaseMetaDate.getAllDatabases();
						for (String dbName : dbNames) {
							comboBox_1.addItem(dbName);
						}
					}

					// 让开始生成代码显示
					button_1.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
					JOptionPane.showMessageDialog(null, "连接数据库失败，请检查连接参数！", "错误提示", JOptionPane.ERROR_MESSAGE);
				}
			}
		});
		// ==================================================获取数据库名结束==================================================

		// ==================================================开始生成代码开始==================================================
		button_1.setBounds(216, 328, 130, 35);
		codeStructFrame.getContentPane().add(button_1);
		button_1.addMouseListener(new MouseAdapter() {
			@SuppressWarnings("static-access")
			@Override
			public void mouseClicked(MouseEvent mouseEvent) {
				// 创建临时缓存数据库
				Map<String, Database> map = new HashMap<String, Database>();

				// 重新拼接数据库地址
				dbType = comboBox_0.getSelectedItem().toString();
				dbIp = textField_0.getText();
				dbPort = textField_1.getText();
				dbUser = textField_2.getText();
				dbPassword = textField_3.getText();
				dbName = comboBox_1.getSelectedItem().toString();

				// 判断是否为空内容
				if ("".equals(dbType)) {
					JOptionPane.showMessageDialog(null, "数据库类型不能为空！", "错误提示", JOptionPane.ERROR_MESSAGE);
					return;
				}
				if ("".equals(dbIp)) {
					JOptionPane.showMessageDialog(null, "数据库地址不能为空！", "错误提示", JOptionPane.ERROR_MESSAGE);
					return;
				}
				if ("".equals(dbPort)) {
					JOptionPane.showMessageDialog(null, "数据库端口不能为空！", "错误提示", JOptionPane.ERROR_MESSAGE);
					return;
				}
				if ("".equals(dbUser)) {
					JOptionPane.showMessageDialog(null, "数据库账户不能为空！", "错误提示", JOptionPane.ERROR_MESSAGE);
					return;
				}
				if ("".equals(dbPassword)) {
					JOptionPane.showMessageDialog(null, "数据库密码不能为空！", "错误提示", JOptionPane.ERROR_MESSAGE);
					return;
				}
				if ("".equals(dbName)) {
					JOptionPane.showMessageDialog(null, "数据库名称不能为空！", "错误提示", JOptionPane.ERROR_MESSAGE);
					return;
				}

				dbUrl = DatabasesConfigUtil.replaceUrlConfig(dbConfig.get(dbType).get("dbUrl"), dbIp, dbPort, dbName);
				dbDriverName = dbConfig.get(dbType).get("dbDriverName");
				dbDataSourceType = dbConfig.get(dbType).get("dbDataSourceType");
				dbDialect = dbConfig.get(dbType).get("dbDialect");
				dbGenerator = dbConfig.get(dbType).get("dbGenerator");

				// 获取数据库所有的表
				DatabaseMetaDataUtil databaseMetaDate = new DatabaseMetaDataUtil(dbDriverName, dbUrl, dbUser, dbPassword);
				List<Table> tableList = databaseMetaDate.getAllTableList();
				List<Table> tables = new ArrayList<Table>();
				for (Table table : tableList) {
					tables.add(table);
					logger.info("读取数据库表信息：" + table);
				}

				// 生成数据库信息参数
				Database database = new Database();
				database.setDbIp(dbIp);
				database.setDbPort(dbPort);
				database.setDbName(dbName);
				database.setDbUrl(dbUrl);
				database.setDbUser(dbUser);
				database.setDbPassword(dbPassword);
				database.setDbType(dbType);
				database.setDbDriverName(dbDriverName);
				database.setDbDataSourceType(dbDataSourceType);
				database.setDbDialect(dbDialect);
				database.setDbGenerator(dbGenerator);
				database.setTables(tables);

				// 装配下一环节的参数
				map.put("database", database);

				// 将配置信息导出保存
				DatabaseConfigUtil.write("database", map);

				// 关闭窗口，进入工程
				new CodeBuilder().main(new String[] {});
				codeStructFrame.setVisible(false);
			}
		});
		// ==================================================开始生成代码结束==================================================
	}

	/**
	 * 功能说明：批量设置文本框内容
	 * 
	 * @param databases
	 * @param comboBox_0
	 */
	private void reloadSettings(Map<String, Map<String, String>> databases, JComboBox<String> comboBox_0, JComboBox<String> comboBox_1) {
		// ==================================================数据库地址开始==================================================
		textField_0.setText(databases.get(comboBox_0.getSelectedItem()).get("dbIp"));
		// ==================================================数据库地址结束==================================================

		// ==================================================数据库端口开始==================================================
		textField_1.setText(databases.get(comboBox_0.getSelectedItem()).get("dbPort"));
		// ==================================================数据库端口结束==================================================

		// ==================================================数据库用户开始==================================================
		textField_2.setText(databases.get(comboBox_0.getSelectedItem()).get("dbUser"));
		// ==================================================数据库用户结束==================================================

		// ==================================================数据库密码开始==================================================
		textField_3.setText(databases.get(comboBox_0.getSelectedItem()).get("dbPassword"));
		// ==================================================数据库编码结束==================================================

		// 清空数据库连接列表
		comboBox_1.removeAllItems();

		// 禁用数据库连接列表
		comboBox_1.setEnabled(false);

		// 禁用开始生成代码
		button_1.setVisible(false);
	}

}
